package com.ncr.travel.appmgr.client.ui;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.LoadEvent;
import com.google.gwt.event.dom.client.LoadHandler;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.OpenHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteHandler;
import com.google.gwt.user.client.ui.FormPanel.SubmitEvent;
import com.google.gwt.user.client.ui.FormPanel.SubmitHandler;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.ncr.travel.appmgr.client.UrlBuilder;
import com.ncr.travel.appmgr.client.model.ScreenConfigurationFactory;
import com.ncr.travel.appmgr.client.view.ConfigEditorView;
import com.ncr.travel.appmgr.model.shared.AvailableGraphics;
import com.ncr.travel.appmgr.model.shared.Graphics;
import com.ncr.travel.appmgr.style.client.AppManagerStyleClientBundle;

/**
 * @author nd185038
 * 
 */
public class GraphicsDiscPanel extends Composite {
    /**
     * Factory for screen config model objects.
     */
	private ScreenConfigurationFactory screenConfigurationFactory;

	DisclosurePanel graphicItemDiscPanel;

	VerticalPanel discPanelImageItemsPanel;

	Label graphicsItemNameLbl;

	Button globalSelectBtn;// = new Button("Select");

	final AppManagerStyleClientBundle resources;

	final Image selectedItemImage = new Image();

	String selectedImageWidth = "";
	String selectedImageHeight = "";
	boolean isImageSelectionChanged = false;

	Graphics graphicItem;

	long screenId;
	private String configurationData;

	/**
	 * @return the itemImage
	 */
	public Image getItemImage() {
		return selectedItemImage;
	}

	/**
	 * @param graphicItem
	 * @param undoButton
	 * @param previewButton
	 * @param confirmButton
	 */
	@SuppressWarnings("unchecked")
	public GraphicsDiscPanel(final ScreenConfigurationFactory screenConfigurationFactory, final String configurationData, final long screenId, final Graphics graphicItem, final ConfigEditorView controls) {
		this.screenConfigurationFactory = screenConfigurationFactory;
		this.configurationData = configurationData;
		this.graphicItem = graphicItem;

		this.screenId = screenId;

		String itemName = graphicItem.getName();

		// ImageResource imageResource;

		final HorizontalPanel graphicsDetailsPanel = new HorizontalPanel();

		graphicItemDiscPanel = new DisclosurePanel();

		discPanelImageItemsPanel = new VerticalPanel();
		discPanelImageItemsPanel.setStyleName("discPanelImageItemsPanel");

		initWidget(graphicItemDiscPanel);

		graphicsDetailsPanel.setStyleName("graphicHorizontalPanel");

		//ND31012012, Styles come from CSS.
		//graphicsDetailsPanel.setWidth("100%");

		graphicsItemNameLbl = new Label();
		
		//ND31012012, Styles come from CSS.
		//graphicsItemNameLbl.setWidth("100px");

		graphicsItemNameLbl.setText(itemName);

		graphicsItemNameLbl.setStyleName("graphicItemLabel");

		graphicsDetailsPanel.add(graphicsItemNameLbl);

		resources = GWT.create(AppManagerStyleClientBundle.class);

		HorizontalPanel addBtnPanel = new HorizontalPanel();
		
		addBtnPanel.setStyleName("addBtnPanel");

		//ND31012012, Styles come from CSS.
		//addBtnPanel.setSize("100%", "30px");

		Button addNewImageBtn = new Button("Add");

		//ND31012012, Commented, size comes from CSS.
		//addNewImageBtn.setSize("75px", "30px");

		addNewImageBtn.setStyleName("addNewImageBtn");

		// Handle event when the user clicks "Add" button to add new image item.
		addNewImageBtn.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {

				// Pop-up a pannel having file-upload item with 'Cancel' and
				// 'Submit' button.
				final PopupPanel form = new PopupPanel(false, true);

				final FormPanel frm = new FormPanel();

				frm.setEncoding(FormPanel.ENCODING_MULTIPART);
				frm.setMethod(FormPanel.METHOD_POST);

				String addFormHandlerUrl = UrlBuilder.createUrl(configurationData).getScreenUriForAddImage(screenId, graphicItem.getId());

				// String addFormHandlerUrl =
				// "http://153.71.90.109:8080/appmanager-web/" + screenId + "/"
				// + graphicItem.getId() + "/addNewImageFormHaldler";

				frm.setAction(addFormHandlerUrl);

				VerticalPanel holder = new VerticalPanel();

				// Good work ND.
				class MyFileUpload extends FileUpload {
					public void onBrowserEvent(Event event) {
						super.onBrowserEvent(event);
						if (DOM.eventGetType(event) == Event.ONCHANGE) {
							((Button) (((HorizontalPanel) (((VerticalPanel) (this.getParent())).getWidget(2))).getWidget(1))).setEnabled(true);

						}
					}
				}

				// final FileUpload upload = new FileUpload();
				final MyFileUpload upload = new MyFileUpload();

				// Inform GWT that we need to receive ONCHANGE events in the
				// first place.
				DOM.sinkEvents(upload.getElement(), Event.ONCHANGE | Event.ONCLICK);

				upload.setName("upload");

				holder.add(upload);

				// \\153.59.141.20\Air3_Dev
				holder.add(new HTML("<hr />"));

				HorizontalPanel cmdButtonsPanel = new HorizontalPanel();

				cmdButtonsPanel.setSize("100%", "100%");

				Button cancelBtn = new Button("Cancel");
				cmdButtonsPanel.add(cancelBtn);

				// Hide the pop-up panel when the user clicks 'Cancel' button.
				cancelBtn.addClickHandler(new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						form.hide();

					}
				});

				final Button submitBtn = new Button("Submit");
				submitBtn.setEnabled(false);
				cmdButtonsPanel.add(submitBtn);

				submitBtn.addClickHandler(new ClickHandler() {
					@Override
					public void onClick(ClickEvent event) {

						frm.submit();
					}

				});

				cmdButtonsPanel.setCellHorizontalAlignment(cancelBtn, HasHorizontalAlignment.ALIGN_LEFT);
				cmdButtonsPanel.setCellVerticalAlignment(cancelBtn, HasVerticalAlignment.ALIGN_MIDDLE);
				cmdButtonsPanel.setCellHorizontalAlignment(submitBtn, HasHorizontalAlignment.ALIGN_RIGHT);
				cmdButtonsPanel.setCellVerticalAlignment(submitBtn, HasVerticalAlignment.ALIGN_MIDDLE);

				holder.add(cmdButtonsPanel);

				frm.setWidget(holder);

				frm.addSubmitHandler(new SubmitHandler() {
					@Override
					public void onSubmit(SubmitEvent arg0) {
						//ND13022012: This event is fired just before the form is submitted. 
						//We can take this opportunity to perform validation.
						
						//Get the file name from the file upload dialog.
						String selectedFileName = upload.getFilename();
						
						//Check if the file name is empty.
						if(selectedFileName.isEmpty())
						{
							//Window.alert("No file selected");
							ErrorDialog ed = new ErrorDialog("No file selected");
							ed.showView();
							submitBtn.setEnabled(false);
							arg0.cancel();
						}
						
						int fileExtensionIndex  = selectedFileName.lastIndexOf(".");
						
						if(fileExtensionIndex == -1)
						{
							//Window.alert("Invalid file without extension");
							ErrorDialog ed = new ErrorDialog("Invalid file without extension");
							ed.showView();
							arg0.cancel();
						}
						else
						{

							String fileExtensionString = selectedFileName.substring(fileExtensionIndex + 1,selectedFileName.length());
							
							if(!(fileExtensionString.equalsIgnoreCase("png") ||
								fileExtensionString.equalsIgnoreCase("jpg") ||
								fileExtensionString.equalsIgnoreCase("jpeg") ||
								fileExtensionString.equalsIgnoreCase("bmp")))
							{
							 
					            //Window.alert("File is not an image file, chosen file extension is: " + fileExtensionString);
								ErrorDialog ed = new ErrorDialog("File is not an image file, chosen file extension is: " + fileExtensionString);
								ed.showView();
								arg0.cancel();
							}							
						}
					}
				});

				frm.addSubmitCompleteHandler(new SubmitCompleteHandler() {

					@Override
					public void onSubmitComplete(SubmitCompleteEvent arg0) {
						
						if(!arg0.getResults().isEmpty())
						{

							AvailableGraphics newGraphicItem = screenConfigurationFactory.availableGraphics().as();
	
							newGraphicItem.setSelected(false);
	
							// Get the user selected image with full path.
							String selectedFileName = upload.getFilename();
	
							// Window.alert(selectedFileName);
							int mid = selectedFileName.lastIndexOf("\\");
	
							selectedFileName = selectedFileName.substring(mid + 1, selectedFileName.length());
	
							// Set the image url.
							int midBaseUrl = graphicItem.getAvailableGraphics().get(0).getUrl().lastIndexOf("/");
							String baseUrl = graphicItem.getAvailableGraphics().get(0).getUrl().substring(0, midBaseUrl);
							// Window.alert("Base url :" + baseUrl);
	
							selectedFileName = baseUrl + "/" + selectedFileName;
	
							// Window.alert("Created url for selected image: " +
							// selectedFileName);
	
							newGraphicItem.setUrl(selectedFileName);
	
							HTML splitter = new HTML("<hr>");
							splitter.setStyleName("graphicDiscsplitter");
							discPanelImageItemsPanel.add(splitter);
							discPanelImageItemsPanel.add(AddGraphicItemInfoPanel(newGraphicItem, controls));// previewButton));
	
							// Add the newly created graphic to the liat of
							// available graphics.
							graphicItem.getAvailableGraphics().add(newGraphicItem);
	
							// previewButton.setEnabled(true);
							controls.enablePreviewControl();
	
							
						}
						else{
							//Window.alert("File upload failed.");
							ErrorDialog ed = new ErrorDialog("File upload failed.");
							ed.showView();
						}
						
						form.hide();
						

					}

				});

				// form.add(holder);
				form.add(frm);

				form.center();
			}

		});

		addBtnPanel.add(addNewImageBtn);

		addBtnPanel.setCellHorizontalAlignment(addNewImageBtn, HasHorizontalAlignment.ALIGN_LEFT);
		addBtnPanel.setCellVerticalAlignment(addNewImageBtn, HasVerticalAlignment.ALIGN_MIDDLE);

		discPanelImageItemsPanel.add(addBtnPanel);

		int numberOfItems = graphicItem.getAvailableGraphics().size();

		for (AvailableGraphics availableGraphic : graphicItem.getAvailableGraphics()) {

			if (availableGraphic.isSelected()) {
				selectedItemImage.setUrl(availableGraphic.getUrl());
				setImageSize(selectedItemImage);
			}

		}
		graphicItemDiscPanel.add(discPanelImageItemsPanel);

		selectedItemImage.addLoadHandler(new LoadHandler() {

			@Override
			public void onLoad(LoadEvent event) {
				if (isImageSelectionChanged) {
					selectedItemImage.setWidth(selectedImageWidth);
					selectedItemImage.setHeight(selectedImageHeight);
					isImageSelectionChanged = false;
				}
				setImageSize(selectedItemImage);

			}

		});

		selectedItemImage.setStyleName("graphicItemImage");

		graphicsDetailsPanel.add(selectedItemImage);

		final Image folderCloseImage = new Image(resources.folder_close());

		folderCloseImage.setStyleName("folderImageClose");

		graphicsDetailsPanel.add(folderCloseImage);

		graphicsDetailsPanel.setCellHorizontalAlignment(graphicsItemNameLbl, HasHorizontalAlignment.ALIGN_LEFT);
		graphicsDetailsPanel.setCellVerticalAlignment(graphicsItemNameLbl, HasVerticalAlignment.ALIGN_MIDDLE);
		graphicsDetailsPanel.setCellHorizontalAlignment(selectedItemImage, HasHorizontalAlignment.ALIGN_CENTER);
		graphicsDetailsPanel.setCellVerticalAlignment(selectedItemImage, HasVerticalAlignment.ALIGN_MIDDLE);
		graphicsDetailsPanel.setCellHorizontalAlignment(folderCloseImage, HasHorizontalAlignment.ALIGN_RIGHT);
		graphicsDetailsPanel.setCellVerticalAlignment(folderCloseImage, HasVerticalAlignment.ALIGN_MIDDLE);

		graphicItemDiscPanel.setHeader(graphicsDetailsPanel);

		final Image folderOpenImage = new Image(resources.folder_open());

		graphicItemDiscPanel.addOpenHandler(new OpenHandler() {
			@Override
			public void onOpen(OpenEvent event) {

				graphicsDetailsPanel.remove(selectedItemImage);
				graphicsDetailsPanel.remove(folderCloseImage);

				folderOpenImage.setStyleName("folderImageOpen");

				graphicsDetailsPanel.add(folderOpenImage);

				if (!(discPanelImageItemsPanel.getWidgetCount() > 1)) {

					int numberOfItems = graphicItem.getAvailableGraphics().size();
					for (AvailableGraphics availableGraphic : graphicItem.getAvailableGraphics()) {

						if (availableGraphic.isSelected())
							selectedItemImage.setUrl(availableGraphic.getUrl());

						discPanelImageItemsPanel.add(AddGraphicItemInfoPanel(availableGraphic, controls));// previewButton));

						if (numberOfItems > 1) {
						    HTML splitter = new HTML("<hr>");
						    splitter.setStyleName("graphicDiscsplitter");
							discPanelImageItemsPanel.add(splitter);
							numberOfItems--;
						}

					}
				}
				
				graphicsDetailsPanel.setCellHorizontalAlignment(folderOpenImage, HasHorizontalAlignment.ALIGN_LEFT);
				graphicsDetailsPanel.setCellVerticalAlignment(folderOpenImage, HasVerticalAlignment.ALIGN_MIDDLE);
			}
		});

		graphicItemDiscPanel.addCloseHandler(new CloseHandler() {
			@Override
			public void onClose(CloseEvent event) {

				graphicsDetailsPanel.add(selectedItemImage);

				graphicsDetailsPanel.remove(folderOpenImage);

				folderCloseImage.setStyleName("folderImageClose");

				graphicsDetailsPanel.add(folderCloseImage);

				graphicsDetailsPanel.setCellHorizontalAlignment(selectedItemImage, HasHorizontalAlignment.ALIGN_CENTER);
				graphicsDetailsPanel.setCellVerticalAlignment(selectedItemImage, HasVerticalAlignment.ALIGN_MIDDLE);
				graphicsDetailsPanel.setCellHorizontalAlignment(folderCloseImage, HasHorizontalAlignment.ALIGN_RIGHT);
				graphicsDetailsPanel.setCellVerticalAlignment(folderCloseImage, HasVerticalAlignment.ALIGN_MIDDLE);

			}
		});

	}

	/**
	 * @return the graphicItemDiscPanel
	 */
	public DisclosurePanel getGraphicItemDiscPanel() {
		return graphicItemDiscPanel;
	}

	/**
	 * @param availableGraphic
	 * @param previewButton
	 * @return HorizontalPanel containing the available image and select button.
	 */
	private HorizontalPanel AddGraphicItemInfoPanel(AvailableGraphics availableGraphic, final ConfigEditorView controls) {

		HorizontalPanel graphicItemInfoPanel = new HorizontalPanel();

		//ND30012012, Commented, size comes from CSS styles
		//graphicItemInfoPanel.setSize("47px", "723px");

		graphicItemInfoPanel.setStyleName("graphicItemInfoPanel");

		Image fileImage = new Image(resources.fileIcon());

		fileImage.setStyleName("fileImage");

		final Image itemImage = new Image(availableGraphic.getUrl());

		final Button selectBtn = new Button("Select");
		selectBtn.setSize("65px", "23px");

		itemImage.addLoadHandler(new LoadHandler() {

			@Override
			public void onLoad(LoadEvent event) {
				setImageSize(itemImage);
				itemImage.setStyleName("itemImage");

			}

		});

		if (availableGraphic.isSelected() == false) {
			selectBtn.setEnabled(true);
			selectBtn.setStyleName("enabledSelectBtn");
		} else {
			globalSelectBtn = selectBtn;
			globalSelectBtn.setStyleName("disabledSelectBtn");
			globalSelectBtn.setEnabled(false);
		}
		
	    graphicItemInfoPanel.add(fileImage);
	    graphicItemInfoPanel.add(itemImage);
	    graphicItemInfoPanel.add(selectBtn);

		//ND30012012, Commented, size comes from CSS styles
		//selectBtn.setSize("75px", "30px");

		selectBtn.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				// TODO Auto-generated method stub
			    if(globalSelectBtn != null) {
			        globalSelectBtn.setEnabled(true);
				    globalSelectBtn.setStyleName("enabledSelectBtn");
			    }
				globalSelectBtn = null;
				globalSelectBtn = selectBtn;
				globalSelectBtn.setEnabled(false);
				globalSelectBtn.setStyleName("disabledSelectBtn");
				String urlOfCurrentImageSelection = ((Image) ((HorizontalPanel) selectBtn.getParent()).getWidget(1)).getUrl();
				selectedItemImage.setUrl(urlOfCurrentImageSelection);
				selectedImageHeight = selectedItemImage.getHeight() + "px";
				selectedImageWidth = selectedItemImage.getWidth() + "px";
				isImageSelectionChanged = true;
				setImageSize(selectedItemImage);

				// previewButton.setEnabled(true);
				controls.enablePreviewControl();

				// change the user selected state of graphic items in the
				// GraphicsItemData.
				for (AvailableGraphics availableGraphic : graphicItem.getAvailableGraphics()) {
					if (availableGraphic.isSelected() == true)
						availableGraphic.setSelected(false);

					String url = availableGraphic.getUrl();

					if (url.equalsIgnoreCase(selectedItemImage.getUrl()))
						availableGraphic.setSelected(true);

				}
			}

		});

		graphicItemInfoPanel.setCellHorizontalAlignment(fileImage, HasHorizontalAlignment.ALIGN_LEFT);
		graphicItemInfoPanel.setCellVerticalAlignment(fileImage, HasVerticalAlignment.ALIGN_MIDDLE);
		graphicItemInfoPanel.setCellHorizontalAlignment(selectBtn, HasHorizontalAlignment.ALIGN_RIGHT);
		graphicItemInfoPanel.setCellVerticalAlignment(selectBtn, HasVerticalAlignment.ALIGN_MIDDLE);
		graphicItemInfoPanel.setCellHorizontalAlignment(itemImage, HasHorizontalAlignment.ALIGN_RIGHT);
		graphicItemInfoPanel.setCellVerticalAlignment(itemImage, HasVerticalAlignment.ALIGN_MIDDLE);

		return graphicItemInfoPanel;

	}

	/**
	 * @param image
	 *            This method is called to resize the image if it is too large.
	 *            Four cases are to be considered: 1. image width > desired
	 *            width and image height is > desired height. 2. image width >
	 *            desired width and image height is <= desired height. 3. image
	 *            width <= desired width and image height is <= desired height.
	 *            4. image width <= desired width and image height is > desired
	 *            height.
	 */
	private void setImageSize(Image image) {

		int desiredHeight = 150;
		int desiredWidth = 200;

		// 1. image width > desired width and image height is > desired height.
		if ((image.getWidth() > desiredWidth) && (image.getHeight() > desiredHeight)) {

			// Check if either width is to be reduced more than the height
			if (((float) desiredWidth / (float) image.getWidth()) > ((float) desiredHeight / (float) image.getHeight())) {

				// Window.alert("H " +
				// ((float)desiredHeight/(float)image.getHeight()) + " < W " +
				// ((float)desiredWidth/(float)image.getWidth()));
				// set height = desired height and reduce the width in
				// proportion.
				image.setWidth(((float) desiredHeight / (float) image.getHeight() * (float) image.getWidth()) + "px");
				image.setHeight(desiredHeight + "px");

				// Window.alert(image.getHeight() + "");
				// Window.alert(image.getWidth() + "");
			} else {
				// Window.alert("W " +
				// ((float)desiredWidth/(float)image.getWidth()) + " < H " +
				// ((float)desiredHeight/(float)image.getHeight()));
				// set width = desired width and reduce the height in
				// proportion.
				image.setHeight(((float) desiredWidth / (float) image.getWidth() * (float) image.getHeight()) + "px");
				image.setWidth(desiredWidth + "px");

				// Window.alert(image.getHeight() + "");
				// Window.alert(image.getWidth() + "");

			}
		} else if ((image.getWidth() > desiredWidth) && (image.getHeight() <= desiredHeight)) {

			// 2. image width > desired width and image height is <= desired
			// height.
			// Here we need to reduce the height proportionately, and set the
			// width = desired width.
			// Window.alert("2. image width > desired width and image height is <= desired height.");
			// Window.alert(desiredWidth + "px W = " + image.getWidth() + "px "
			// + " " + (((float)desiredWidth/(float)image.getWidth()) *
			// (float)image.getHeight()));
			image.setHeight(((float) desiredWidth / (float) image.getWidth() * (float) image.getHeight()) + "px");
			image.setWidth(desiredWidth + "px");

			// Window.alert(image.getHeight() + "");
			// Window.alert(image.getWidth() + "");

		} else if ((image.getWidth() <= desiredWidth) && (image.getHeight() > desiredHeight)) {

			// 4. image width <= desired width and image height is > desired
			// height.
			// Here we need to reduce the width proportionately, and set the
			// height = desired height.
			// Window.alert("4. image width <= desired width and image height is > desired height.");
			image.setWidth(((float) desiredHeight / (float) image.getHeight() * (float) image.getWidth()) + "px");
			image.setHeight(desiredHeight + "px");

			// Window.alert(image.getHeight() + "");
			// Window.alert(image.getWidth() + "");
		} else {
			// 3. image width <= desired width and image height is <= desired
			// height.
			// Do nothing. Keep the original sizes.
			// Window.alert("Keep original image size: W = " + image.getWidth()
			// + " H = " + image.getHeight());

			// Window.alert(image.getHeight() + "");
			// Window.alert(image.getWidth() + "");
		}

	}
}
